<?php
/**
 * Created by PhpStorm.
 * User: function
 * Date: 2018-04-19
 * Time: 23:19
 */

namespace app\common\logic;
use app\common\model\Order;
use app\common\model\UnifiedOrder;
use app\common\logic\Logic;
use app\common\model\Pay;

class PayLogic extends Logic
{
    

    
    /**
     * @param $out_trade_no
     * @desc 重新发起支付，如果订单还可以用就直接发。如果过期就显示过期了吧
     */
    public function PayUnifiedOrderAgain($trade_no){
    
        $order = Order::get(['trade_no'=>$trade_no]);
        $unifiedOrder = UnifiedOrder::get(['order_id'=>$order->id]);
        $out_trade_no = $unifiedOrder->out_trade_no;
        
        $pay = Pay::get(['out_trade_no'=>$out_trade_no]);
        
        if($pay->status==1){
            return callerror('该订单已经支付过');
        }
        
        //重新生成第三方订单号,这里会有一个问题。就是需要去关闭微信之前的订单号。可以不这么做，但是对账挺麻烦的
        $newUnifiedOrder = $this->createUuid();
        
        //1.替换掉和订单绑定的
//        $unifiedOrders = UnifiedOrder::where('out_trade_no',$out_trade_no)->select();
//        foreach ($unifiedOrders as $unifiedOrder){
//            log::info($unifiedOrder->order_id.'订单的第三方支付号，统一由'.$unifiedOrder->out_trade_no.'更换成'.$newUnifiedOrder);
//            $unifiedOrder->out_trade_no = $newUnifiedOrder;
//            $unifiedOrder->isUpdate()->save();
//        }
        
        //2.替换掉和支付表绑定的
        log::info($pay->id.'支付记录的第三方支付号，统一由'.$pay->out_trade_no.'更换成'.$newUnifiedOrder);
        $pay->out_trade_no = $newUnifiedOrder;
        $pay->isUpdate()->save();
        
        
        
    }
    
    
    public function mixinOrder($out_trade_no){
        $orderIds = UnifiedOrder::where('out_trade_no',$out_trade_no)->field('order_id')->select();
       
        if(count($orderIds)<1){
            return callerror('该大订单下没有子订单');
        }
        
        $allAmount = 0;
        foreach ($orderIds as $orderId){
            
            $order = Order::where('id',$orderId['order_id'])->field('id,amount,status')->find();
            if(!$order){
                return callerror($orderId['order_id'].'子订单获取失败');
            }
            if($order->status!=0){
                return callerror('已有部分子订单支付，请进入订单中心分开支付');
            }
            
            $allAmount += $order['amount'];
            
        }
        if($allAmount<=0){
            return callerror('订单金额为0,无需支付');
        }

        return call(1,'订单金额计算成功',$allAmount);
    }
    
    
    /**
     * @param $channel 支付渠道
     * @param $body 商品描述，微信建议的命名规则 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_2
     * @param $out_trade_no 订单号
     * @param $total_fee 订单金额，组多两位小数。（转换成分的操作由后台来做即可）
     * @param $openid  公众号支付，此参数必传，此参数为微信用户在商户对应appid下的唯一标识
     */
    public function unifiedpay($pay){
        
        $rule = [
            'channel|支付类型'  => 'require',
            'body|商品描述必填'   => 'require',
            'out_trade_no|支付公共订单号'   => 'require',
            'total_fee|金额'   => 'require',
            'open_id|openid'   => 'require',
        ];

        $this->validate($pay,$rule);//表单校验
        $isPay = Pay::get(['out_trade_no'=>$pay['out_trade_no']]);
        if($isPay){
            return callerror('已经预下单');
        }
        
//        if($isPay['status'] != 0){
//            return callerror('该公共订单已经支付');
//        }
        $model = new Pay();
        $model->allowField(true)->save($pay);
        if(!$model->id){
            return callerror('保存统一支付信息失败');
        }
        if(ENV=='development'){
            $pay['total_fee'] = 0.01;//测试环境下，所有订单都是0.01元
        }
        
        switch ($pay['channel']){
            case 'wx_wap':
                $rt = $this->wx('wap',$pay['body'],$pay['out_trade_no'],$pay['total_fee']);
                break;
            case 'wx_app':
                $rt = $this->wx('app',$pay['body'],$pay['out_trade_no'],$pay['total_fee']);
                break;
            case 'wx_pub':
                if(!$pay['open_id']){
                    callerror('公众号内下单需要需要openid参数');
                };
                $rt = $this->wx('pub',$pay['body'],$pay['out_trade_no'],$pay['total_fee'],$pay['open_id']);
                break;
            case 'ali_wap':
                $rt = $this->ali('wap',$pay['body'],$pay['out_trade_no'],$pay['total_fee']);
                break;
            case 'ali_app':
                $rt = $this->ali('app',$pay['body'],$pay['out_trade_no'],$pay['total_fee']);
                break;
            case 'apple':
                $rt = $this->apple('pub',$pay['body'],$pay['out_trade_no'],$pay['total_fee']);
                break;
        }
        return $rt;
        
        
    }
    
    protected function wx($channel,$body,$out_trade_no,$total_fee,$openid=null){
        
        $payOrder = [
            'openid'=>$openid?$openid:null,
            'body'=>$body,
            'out_trade_no'=>$out_trade_no,
            'total_fee'=>floor($total_fee*100)//微信只支持分
        ];
        
        switch ($channel){
            case 'pub':
                $pay = new \Pay\Pay(config('thirdaccount.pay_wechat_pub'));
                $gateway = 'mp';
                break;
            case 'wap':
                $pay = new \Pay\Pay(config('thirdaccount.pay_wap'));
                $gateway = 'wap';
                break;
            case 'app':
                $pay = new \Pay\Pay(config('thirdaccount.pay_app'));
                $gateway = 'app';
                break;
            default:
                callerror('微信支付类型错误，只允许wap/app/Pub');
                break;
        }
        
        try {
            $payInfo = $pay->driver('wechat')->gateway($gateway)->apply($payOrder);
            if($channel=='app'){
                $payAppConfig = config('thirdaccount.pay_app');
                $payInfo['mch_id'] = $payAppConfig['wechat']['mch_id'];
            }
            
            $pay = Pay::get(['out_trade_no'=>$out_trade_no]);
            $pay->content = json_encode($payInfo);
            $pay->isUpdate()->save();

            return callsuccess($payInfo);
            
        } catch (Exception $e) {
            
            return callerror("创建订单失败，" . $e->getMessage());
        }
        
    }
    
    public function ali($channel,$body,$out_trade_no,$total_fee){
        
        $payOrder = [
            'subject'=>$body,
            'out_trade_no'=>$out_trade_no,
            'total_amount'=>$total_fee//微信只支持分
        ];
        
        switch ($channel){
            case 'wap':
                $payOrder['product_code'] = 'QUICK_WAP_WAY';
                $pay = new \Pay\Pay(config('thirdaccount.pay_wap'));
                $gateway = 'wap';
                break;
            case 'app':
                $payOrder['product_code'] = 'QUICK_MSECURITY_PAY';
                $pay = new \Pay\Pay(config('thirdaccount.pay_app'));
                $gateway = 'app';
                break;
            default:
                callerror('支付宝支付类型错误，只允许wap/app');
                break;
        }
        
        try {
            $payInfo = $pay->driver('alipay')->gateway($gateway)->apply($payOrder);
//            var_dump($payInfo);die;
            $rt = ['payInfo'=>$payInfo];
            api(100,'支付参数获取成功',$rt);
        } catch (Exception $e) {
            
            callerror("创建订单失败，" . $e->getMessage());
        }
        
    }
    
    
   
    
}